home *** CD-ROM | disk | FTP | other *** search
Text File | 1999-05-17 | 66.2 KB | 2,175 lines | [TEXT/MPS ] |
- /*
- File: FWiXDriver.c
-
- Contains: Driver software for FireWire File Exchange.
-
- Version: 1.0
-
- Written by: Jay Lloyd
-
- Copyright: © 1996-1999 by Apple Computer, Inc., all rights reserved.
-
- File Ownership:
-
- DRI: Jay Lloyd
-
- Other Contact:
-
- Technology: FireWire
-
- Writers:
-
- (jkl) Jay Lloyd
-
- Change History (most recent first):
-
- <FW31> 4/8/99 jkl Got rid of unused variable in DoDriverIO
- <FW30> 4/8/99 jkl Added DoDriverIO routine so fwix can fake being a GDF.
- <FW29> 7/7/98 jkl Deallocate node's data buffer address space when closing node.
- <FW28> 1/15/98 jkl Update for new headers.
- <FW27> 5/28/97 jkl Added a check for control packet index equal to 1 for a node
- being restarted. Cleaned up some of the inUse and timing checks
- added in last revision to investigate 5+ node problem.
- <FW26> 5/27/97 jkl Added a control packet indexing function to make sure control
- packets are handled only once. Changed the flow control timer to
- send flow control requests until a reply is received. This would
- fix a case where a flow control request never got a reply.
- Added more error checking and in use checking to investigate 5+
- node problem.
- <FW25> 5/15/97 jkl Added a checksum routine around send data and data done. Added
- an index to the flow control messages to only handle a reply
- from the latest request. Put a check around sendpacket to make
- sure it is not reentered.
- <FW24> 2/27/97 jkl Modified the WriteDataComplete routine to turn off flow control.
- This will cause a flow control request and reply to be sent to
- ensure the receive data buffer does not get overwritten with
- more data before the receiver reads the existing data out of the
- buffer. Reduced flow control retry time from 100 to 10 ms to
- reduce transfer stalls.
- <FW23> 2/21/97 ES Added in use flags for all FWCommandObjects. Changed FWXClose to
- wait for all of these flags to clear before doing any closing
- activity. Removed wait on writePending. This fixes a hang on
- closing bug.
- <FW22> 2/21/97 EA Added option to send diagnostic messages to FireBug.
- <FW21> 2/21/97 jkl Modified data transmissions to be sent to non-notify address
- space.
- <FW20> 2/20/97 ES Changed FWClientAsynchRequestParams buffer field to
- receiveBuffer.
- <FW19> 2/19/97 jkl Added a flow control send pending flag to make sure two messages
- do not get sent at one time. Moved available buffer counts from
- write completion routine to write routine.
- <FW18> 2/14/97 jkl Changed the flow control mechanism so the sender has to request
- from the receiver how many packets he can send.
- <FW17> 2/13/97 jkl Added FlowControl packet counter to make sure flow control is
- started properly.
- <FW16> 2/13/97 jkl Changed flow control to just keep up with number of data packets
- available and sent. The flow control message is only sent when
- all of the read packets have been received and are available,
- thus the sender will stall after each number of sends. Changed
- write notify routine to complete read data transaction when
- requested data is equal to received data.
- <FW15> 2/11/97 ES Added closed boolean to FWXNodeData record. Added checks for
- node being closed to prevent any writes going out or being
- processed when we're closing a node connection. Changed write
- queue deallocation to wait until no more writes are pending
- before deallocating queue.
- <FW14> 2/11/97 jkl Added support for read control and data queues. Changed flow
- control to a you can send me this much mechanism. Moved
- FWXCommandComplete routine to the family.
- <FW13> 2/2/97 jkl Modified flow control time delay to check more often if it is ok
- to write and write routine to handle writing buffers larger than
- the allocated firewire buffer size.
- <FW12> 1/27/97 ES Changed FWXWrite to make sure there is still an item on the
- write queue before processing the head of the queue (a race
- condition was happening here). Changed FWXCloseNode to check if
- the read and write queues were non-nil before deallocating.
- <FW11> 1/16/97 ES Changed FWXCreatePDriverUnitDirectory to set CSRROMEntryID's to
- invalid before using them. Also, added code to deallocate entry
- ID's.
- <FW10> 1/16/97 jkl Cleaned up read/write buffers on close.
- <FW9> 1/8/97 ES Changed to a FireWire protocol driver. Removed fixed FireWire
- address allocation.
- <FW8> 12/27/96 ES Changed a bunch of "FWDriver"s to "FWClient"s.
- <FW7> 12/16/96 ES Changed to work with new read/write/lock request/complete
- processing mechanism.
- <FW6> 12/3/96 ES Added kFWFixedAddress flag to FWAllocateAddressSpace.
- <FW5> 11/13/96 jkl Moved from DoDriverIO interface back to CallDriver. Added
- multiple machine support. Added packet receive buffering.
- <FW4> 10/31/96 jkl Added flow control constants.
- <FW3> 10/13/96 jkl Added a basic flow control capability to turn off transmission
- when the number of received buffers is low. All queue routines
- are now the dsl queue routines. The ioMisc field in a parameter
- block is now used to identify the packet type. For control
- packets, the packet type is still also in the first long word
- of the buffer. A sendpacket routine is now called by the write
- handler and the write completion handler to send a packet. Fork
- data is sent to a separate address space that is now set to write
- notify.
- <FW2> 10/3/96 jkl Changed to use set driver interface calls rather than driver
- interface table.
- <FW1> 10/2/96 jkl initial check-in, copied from avt driver
- Added DoDriverIO interface.
-
- */
-
- #include <Types.h>
- #include <Errors.h>
- #include <Devices.h>
- #include <DriverServices.h>
- #include <FireWire.h>
-
- #include "FWiX.h"
- #include "FWiXDriver.h"
-
- #include <stdio.h>
- char debugStr[256];
- static pascal void FWDebugStr(
- ConstStr255Param debuggerMsg)
- {
- #ifdef FW_DEBUG_BUILD
- #if FW_DEBUG_BUILD
- DebugStr (debuggerMsg);
- #endif
- #endif
- }
-
-
- // define FireBug to enable sending diagnostic messages to FireBug on the fly.
- // WARNING: Read the notes below first. Be sure use "tcode on 1" in FireBug
- // so that you can see the messages. [Also use "ack 0" if you don't want to
- // see many other packets]
-
- //#define FireBug
- #ifdef FireBug
- static char fireBug[256];
- static FWReferenceID fireBugID;
- static FWCommandObjectID fireBugCommandObjectID;
- static UInt32 fireBugNeedCommandObject = 1;
-
- static void FireBugMsg (char * msg)
- {
- FWTopologyMap topology;
- OSStatus status;
-
- if (fireBugNeedCommandObject) return;
-
- // It would probably be more safe to add a mechanism to make sure the
- // most recent FireBugMsg completed before we recycle the command object.
- // But I expect that the FWGetTopologyMap will probably take care of this.
-
- status = FWGetTopologyMap (fireBugID, &topology);
- status = FWSetAsynchCommandGeneration (fireBugCommandObjectID, topology.generationNumber);
- status = FWSetAsynchCommandBuffer (fireBugCommandObjectID, msg);
- status = FWSetAsynchCommandLength (fireBugCommandObjectID, strlen (msg) + 1);
- status = FWWrite (fireBugCommandObjectID);
- }
-
- static void FireBugPrep (FWReferenceID tempID)
- {
- OSStatus status;
-
- if (fireBugNeedCommandObject)
- {
- status = FWAllocateAsynchCommandObject (&fireBugCommandObjectID);
- if (status == noErr)
- {
- FWGetLocalFWReferenceIDFromFWReferenceID (tempID, &fireBugID);
-
- FWSetFWCommandParams(fireBugCommandObjectID, fireBugID, 0, nil, 0);
- FWSetCommonAsynchCommandParams (fireBugCommandObjectID,
- 0x42420000, 0x00000000,
- (Ptr) fireBug, sizeof (fireBug));
- FWSetAsynchCommandMaxRetries (fireBugCommandObjectID, 0);
- FWSetAsynchCommandMaxPayloadSize (fireBugCommandObjectID, 512);
- FWSetAsynchCommandTransferFlags (fireBugCommandObjectID,
- kFWAsynchAbsoluteAddress |
- kFWAsynchOverrideMaxPayload);
- }
-
- fireBugNeedCommandObject = 0;
- }
- }
- #endif
-
-
- ////////////////////////////////////////////////////////////////////////////////
- //
- // Internal procedure prototypes.
- //
-
- static void HandleFlowControlNotify (
- FWXNodeDataPtr pFWXNodeData,
- Ptr pMessage);
-
- static void HandleControlNotify (
- FWXNodeDataPtr pFWXNodeData,
- Ptr pMessage,
- UInt32 msgLength);
-
- static void HandleDataDone (
- FWXNodeDataPtr pFWXNodeData,
- UInt32 count,
- UInt32 checkSum);
-
- static OSStatus FWPDriverUnitAdded (
- FWPDriverID fwPDriverID,
- UInt32 fwPDriverSpecificData,
- FWUnitID fwUnitID);
-
- static OSStatus FWPDriverUnitRemoved (
- FWPDriverID fwPDriverID,
- UInt32 fwPDriverSpecificData,
- FWUnitID fwUnitID);
-
- static void FlowControlComplete (
- FWCommandObjectID fwCommandObjectID,
- OSStatus commandStatus,
- UInt32 completionProcData);
-
- static void FlowControlReplyComplete (
- FWCommandObjectID fwCommandObjectID,
- OSStatus commandStatus,
- UInt32 completionProcData);
-
- static OSStatus FWXRead (
- FWXAsynchParamsPtr pFWXAsynchParams);
-
- static OSStatus FWXWrite (
- FWXAsynchParamsPtr pFWXAsynchParams);
-
- static void DataDoneComplete(
- FWCommandObjectID fwCommandObjectID,
- OSStatus commandStatus,
- UInt32 completionProcData);
-
- static void HandleWriteDataComplete(
- FWCommandObjectID fwCommandObjectID,
- FWXNodeDataPtr pFWXNodeData,
- IOParamPtr pCompleteIOPb);
-
- static void HandleWriteControlComplete(
- FWCommandObjectID fwCommandObjectID,
- FWXNodeDataPtr pFWXNodeData,
- IOParamPtr pCompleteIOPb);
-
- static void FWXWriteCompletion (
- FWCommandObjectID fwCommandObjectID,
- OSStatus commandStatus,
- UInt32 completionProcData);
-
- static OSStatus RetryFlowControl (
- void *p1,
- void *p2);
-
- static OSStatus SendDataPacket(
- FWXNodeDataPtr pFWXNodeData,
- IOParamPtr pb,
- UInt32 length);
-
- static OSStatus SendControlPacket(
- FWXNodeDataPtr pFWXNodeData,
- IOParamPtr pb,
- UInt32 length);
-
- static OSStatus SendPacket (
- FWXNodeDataPtr pNodeData);
-
- static OSStatus FWXInitialize (
- FWXInitializeParamsPtr pFWXInitializeParams);
-
- static OSStatus FWXCreatePDriverUnitDirectory (
- FWXDriverDataPtr pFWXDriverData,
- CSRROMEntryID *pFWPDriverCSRROMUnitDirID);
-
- static OSStatus FWXTerminate (
- FWXTerminateParamsPtr pFWXTerminateParams);
-
- static OSStatus FWXOpenNode (
- FWXOpenNodeParamsPtr pFWXInitializeParams);
-
- static OSStatus FWXCloseNode (
- FWXNodeDataPtr pFWXNodeData);
-
- static OSStatus SetupIOQueues (
- FWXNodeDataPtr pFWXNodeData);
-
- static OSStatus FWXGetNodeDataFromNodeID (
- FWXDriverDataPtr pFWXDriverData,
- UInt32 generation,
- UInt32 nodeID,
- FWXNodeDataPtr *ppFWXNodeData);
-
- ////////////////////////////////////////////////////////////////////////////////
- //
- // The driver descriptor.
- //
-
- DriverDescription TheDriverDescription =
- {
- kTheDescriptionSignature,
- kInitialDriverDescriptor,
- {
- "\pFWiX",
- 1, 0, developStage, 1,
- },
- {
- 0 // driver runtime options
- | (0 * kDriverIsLoadedUponDiscovery)
- | (0 * kDriverIsOpenedUponLoad)
- | (1 * kDriverIsUnderExpertControl)
- | (1 * kDriverIsConcurrent)
- | (1 * kDriverQueuesIOPB),
- "\pFWiXDriver",
- },
-
- 1,
- kServiceCategoryNdrvDriver,
- kServiceCategoryFWiX,
- // 0, // delete this
- 1,0,0,0
- };
-
- FWPDriverDescription ThePDriverDescription =
- {
- kTheFWPDriverDescriptionSignature,
- kInitialFWPDriverDescriptor,
-
- kServiceCategoryFWDriver,
- 0,0,developStage,0,
-
- 0,
- "\pFWiX"
- };
-
-
- ////////////////////////////////////////////////////////////////////////////////
- //
- // DoDriverIO
- //
- // Main entry point.
- //
-
- OSErr DoDriverIO(
- AddressSpaceID addressSpaceID,
- IOCommandID ioCommandID,
- IOCommandContents ioCommandContents,
- IOCommandCode ioCommandCode,
- IOCommandKind ioCommandKind)
- {
- OSErr err = noErr;
-
- switch (ioCommandCode)
- {
- default:
- err = noErr;
- }
-
- // complete the command
- if (ioCommandKind == kImmediateIOCommandKind)
- return err;
- else
- return IOCommandIsComplete(ioCommandID, err);
-
- return err;
- }
-
-
- ////////////////////////////////////////////////////////////////////////////////
- //
- // FWClientWriteRequestInterface
- //
- // Handle writes to the client. Check the type of received data by address
- // space id. Set flow control information. If the data is control information
- // send any file data information to the application then send the control
- // information. If the data is file data add it to the receive buffer, if it
- // overflows the receive buffer, send the buffer to the app and get a new one.
- //
-
- OSStatus FWClientWriteCompleteInterface(
- FWClientAsynchRequestParamsPtr
- pFWClientAsynchRequestParams,
- UInt32 *pCommandAcceptance)
- {
- FWXDriverDataPtr pFWXDriverData;
- FWXNodeDataPtr pFWXNodeData;
- OSStatus status = noErr;
-
- // recover our node data
- //zzz check status
- pFWXDriverData = (FWXDriverDataPtr) pFWClientAsynchRequestParams->pAddressSpecificData;
- status = FWXGetNodeDataFromNodeID (pFWXDriverData,
- pFWClientAsynchRequestParams->generation,
- pFWClientAsynchRequestParams->sourceID,
- &pFWXNodeData);
-
- if (status == noErr)
- {
- if (pFWClientAsynchRequestParams->fwAddressSpaceID == pFWXDriverData->fcAddressSpaceID)
-
- HandleFlowControlNotify (pFWXNodeData,
- pFWClientAsynchRequestParams->receiveBuffer);
-
- else if (pFWClientAsynchRequestParams->fwAddressSpaceID == pFWXDriverData->controlAddressSpaceID)
-
- HandleControlNotify (pFWXNodeData,
- pFWClientAsynchRequestParams->receiveBuffer,
- pFWClientAsynchRequestParams->length);
- }
-
- // Complete FireWire client command.
- FWClientCommandIsComplete
- (pFWClientAsynchRequestParams->fwClientInterfaceParams.fwClientCommandID,
- status);
-
- // Return command acceptance.
- //zzz is this the right way? If we've completed the command, we can accept more.
- *pCommandAcceptance = kFWClientCommandAcceptNoMore;
-
- return status;
- }
-
- ////////////////////////////////////////////////////////////////////////////////
- //
- // HandleFlowControlNotify
- //
- // Handle notification of a flow control message received. If the message
- // is a request, reply with the appropriate flow control value. If the
- // message is a reply and there are now receive buffers available, try
- // sending a packet. If there are no buffers available start a timer to
- // wait and then send another flow control request.
- //
-
- static void HandleFlowControlNotify (
- FWXNodeDataPtr pFWXNodeData,
- Ptr pMessage)
- {
- UInt32 fcPacketCount;
- UInt32 messageType;
- AbsoluteTime fcRequestDelay;
- OSStatus status = noErr;
-
- messageType = ((UInt32 *) pMessage)[0];
- switch (messageType)
- {
- case kFCDataRequest:
- if (!pFWXNodeData->fcReplyCommandObjectInUse)
- {
- pFWXNodeData->fcReplyBuffer[0] = kFCDataReply;
- pFWXNodeData->fcReplyBuffer[1] = pFWXNodeData->dataPbCount;
- pFWXNodeData->fcReplyBuffer[2] = ((UInt32 *) pMessage)[2];
- pFWXNodeData->fcReplyCommandObjectInUse = true;
- FWSetFWCommandCompletionProcData (pFWXNodeData->fcReplyCommandObjectID, (UInt32) pFWXNodeData);
- FWSetCommonAsynchCommandParams (pFWXNodeData->fcReplyCommandObjectID,
- pFWXNodeData->fwxUnitInfo.fcAddress.addressHi,
- pFWXNodeData->fwxUnitInfo.fcAddress.addressLo,
- (Ptr) pFWXNodeData->fcReplyBuffer,
- kFlowControlSize);
- status = FWWrite(pFWXNodeData->fcReplyCommandObjectID);
- if (status != noErr)
- pFWXNodeData->fcReplyCommandObjectInUse = false;
- }
- break;
-
- case kFCControlRequest:
- if (!pFWXNodeData->fcReplyCommandObjectInUse)
- {
- pFWXNodeData->fcReplyBuffer[0] = kFCControlReply;
- pFWXNodeData->fcReplyBuffer[1] = pFWXNodeData->controlPbCount;
- pFWXNodeData->fcReplyBuffer[2] = ((UInt32 *) pMessage)[2];
- pFWXNodeData->fcReplyCommandObjectInUse = true;
- FWSetFWCommandCompletionProcData (pFWXNodeData->fcReplyCommandObjectID, (UInt32) pFWXNodeData);
- FWSetCommonAsynchCommandParams (pFWXNodeData->fcReplyCommandObjectID,
- pFWXNodeData->fwxUnitInfo.fcAddress.addressHi,
- pFWXNodeData->fwxUnitInfo.fcAddress.addressLo,
- (Ptr) pFWXNodeData->fcReplyBuffer,
- kFlowControlSize);
- status = FWWrite(pFWXNodeData->fcReplyCommandObjectID);
- if (status != noErr)
- pFWXNodeData->fcReplyCommandObjectInUse = false;
- }
- break;
-
- case kFCDataReply:
- fcPacketCount = ((UInt32 *) pMessage)[2];
- CancelTimer(pFWXNodeData->fcTimerID, &fcRequestDelay);
- if (fcPacketCount == pFWXNodeData->fcIndex)
- {
- pFWXNodeData->fcIndex++;
- pFWXNodeData->dataPbAvail = ((SInt32 *) pMessage)[1];
- if (pFWXNodeData->dataPbAvail > 0)
- {
- if (pFWXNodeData->fcStopSend)
- {
- // there were no buffers before, now there are some, restart sending
- pFWXNodeData->fcStopSend = false;
- status = SendPacket(pFWXNodeData);
- }
- }
- else
- {
- // still no buffers available, reset timer
- fcRequestDelay = AddAbsoluteToAbsolute (UpTime (), DurationToAbsolute(20)); // 20 milliseconds
- status = SetInterruptTimer (&fcRequestDelay, // JKL *** what's a good delay
- RetryFlowControl,
- (void *) pFWXNodeData,
- &pFWXNodeData->fcTimerID);
- }
- }
- else
- {
- // received flow control message out of order, retry
- fcRequestDelay = AddAbsoluteToAbsolute (UpTime (), DurationToAbsolute(20)); // 20 milliseconds
- status = SetInterruptTimer (&fcRequestDelay, // JKL *** what's a good delay
- RetryFlowControl,
- (void *) pFWXNodeData,
- &pFWXNodeData->fcTimerID);
- }
- break;
-
- case kFCControlReply:
- fcPacketCount = ((UInt32 *) pMessage)[2];
- CancelTimer(pFWXNodeData->fcTimerID, &fcRequestDelay);
- if (fcPacketCount == pFWXNodeData->fcIndex)
- {
- pFWXNodeData->fcIndex++;
- pFWXNodeData->controlPbAvail = ((SInt32 *) pMessage)[1];
- if (pFWXNodeData->controlPbAvail > 0)
- {
- if (pFWXNodeData->fcStopSend)
- {
- pFWXNodeData->fcStopSend = false;
- status = SendPacket(pFWXNodeData);
- }
- }
- else
- {
- // still no buffers available, reset timer
- fcRequestDelay = AddAbsoluteToAbsolute (UpTime (), DurationToAbsolute(20)); // 20 milliseconds
- status = SetInterruptTimer (&fcRequestDelay, // JKL *** what's a good delay
- RetryFlowControl,
- (void *) pFWXNodeData,
- &pFWXNodeData->fcTimerID);
- }
- }
- else
- {
- fcRequestDelay = AddAbsoluteToAbsolute (UpTime (), DurationToAbsolute(20)); // 10 milliseconds
- status = SetInterruptTimer (&fcRequestDelay, // JKL *** what's a good delay
- RetryFlowControl,
- (void *) pFWXNodeData,
- &pFWXNodeData->fcTimerID);
- }
- break;
-
- case kAddressInfoRequest:
- if (!pFWXNodeData->fcReplyCommandObjectInUse)
- {
- pFWXNodeData->remoteDataAddress.addressHi = ((UInt32 *) pMessage)[1];
- pFWXNodeData->remoteDataAddress.addressLo = ((UInt32 *) pMessage)[2];
- pFWXNodeData->fcReplyBuffer[0] = kAddressInfoReply;
- pFWXNodeData->fcReplyBuffer[1] = pFWXNodeData->localDataAddress.addressHi;
- pFWXNodeData->fcReplyBuffer[2] = pFWXNodeData->localDataAddress.addressLo;
- pFWXNodeData->fcReplyCommandObjectInUse = true;
- FWSetFWCommandCompletionProcData (pFWXNodeData->fcReplyCommandObjectID, (UInt32) pFWXNodeData);
- FWSetCommonAsynchCommandParams (pFWXNodeData->fcReplyCommandObjectID,
- pFWXNodeData->fwxUnitInfo.fcAddress.addressHi,
- pFWXNodeData->fwxUnitInfo.fcAddress.addressLo,
- (Ptr) pFWXNodeData->fcReplyBuffer,
- kFlowControlSize);
- status = FWWrite(pFWXNodeData->fcReplyCommandObjectID);
- if (status != noErr)
- pFWXNodeData->fcReplyCommandObjectInUse = false;
- }
- else
- {
- FWDebugStr("\paddress info request, object in use");
- }
- break;
-
- case kAddressInfoReply:
- pFWXNodeData->remoteDataAddress.addressHi = ((UInt32 *) pMessage)[1];
- pFWXNodeData->remoteDataAddress.addressLo = ((UInt32 *) pMessage)[2];
- break;
-
- default:
- sprintf(debugStr,"fcNotify, message type unknown: %d", messageType);
- FWDebugStr((ConstStr255Param) c2pstr(debugStr));
- break;
- }
-
- if (status != noErr)
- {
- sprintf(debugStr,"fcNotify, error in FWWrite: %d", status);
- FWDebugStr((ConstStr255Param) c2pstr(debugStr));
- }
- }
-
- ////////////////////////////////////////////////////////////////////////////////
- //
- // HandleControlNotify
- //
- // Handle notification of a control message received. If the message is data
- // done, complete the data request, else complete the control request.
- //
-
- static void HandleControlNotify (
- FWXNodeDataPtr pFWXNodeData,
- Ptr pMessage,
- UInt32 msgLength)
- {
- IOParamPtr pb;
- UInt32 packetType;
- UInt32 packetIndex;
- OSStatus status = noErr;
-
-
- packetIndex = ((UInt32 *) pMessage)[0];
- if ((packetIndex > pFWXNodeData->lastIndex) || (packetIndex == 1)) // will be one if fwix is closed
- { // and opened on other machine
- pFWXNodeData->lastIndex = packetIndex;
- packetType = ((UInt32 *) pMessage)[1];
-
- if (packetType == kDataDone)
- {
- HandleDataDone(pFWXNodeData, ((UInt32 *) pMessage)[2], ((UInt32 *) pMessage)[3]);
- }
- else
- {
- // handle control packet
- pb = (IOParamPtr) pFWXNodeData->pReadControlQHdr->qHead;
- if (pb != nil)
- {
- pFWXNodeData->controlPbCount--;
- if (pFWXNodeData->controlPbCount < 0)
- FWDebugStr("\pcontrol buffer count < 0, ControlNotify");
- PBDequeueFirst(pFWXNodeData->pReadControlQHdr, (QElemPtr *) &pb);
- BlockMoveData(pMessage, pb->ioBuffer, msgLength);
- pb->ioActCount = msgLength;
- pb->ioMisc = (Ptr) packetType;
- FWXCommandIsComplete(pb, status);
- }
- else
- {
- FWDebugStr("\pNo receive control buffer, WriteNotify");
- }
- }
- }
- else
- {
- sprintf(debugStr,"echo packet, last: %ld, received: %ld", pFWXNodeData->lastIndex, packetIndex);
- FWDebugStr((ConstStr255Param) c2pstr(debugStr));
- }
- }
-
- ////////////////////////////////////////////////////////////////////////////////
- //
- // HandleDataDone
- //
- // Handle notification of a data done message. If the data completes the
- // request, send the packet to the app. If the data overflows the request, send
- // the current packet to the app and start a new one. Otherwise just copy the data
- // into the current packet.
- //
-
- static void HandleDataDone (
- FWXNodeDataPtr pFWXNodeData,
- UInt32 count,
- UInt32 checkSum)
- {
- IOParamPtr pb;
- UInt32 byteCount;
- UInt32 dataSum;
- OSStatus status = noErr;
-
- pb = (IOParamPtr) pFWXNodeData->pReadDataQHdr->qHead;
- if (pb != nil)
- {
- dataSum = 0;
- for (byteCount = 0; byteCount < count; ++byteCount)
- dataSum += (pFWXNodeData->dataBuffer)[byteCount];
-
- if (dataSum != checkSum)
- {
- status = badCksmErr;
- sprintf(debugStr,"Checksum error, expected: %ld, received: %ld", checkSum, dataSum);
- FWDebugStr((ConstStr255Param) c2pstr(debugStr));
- }
-
- BlockMoveData (pFWXNodeData->dataBuffer,
- pb->ioBuffer + pb->ioActCount,
- count);
- pb->ioActCount += count;
-
- pFWXNodeData->dataPbCount--;
- if (pFWXNodeData->dataPbCount < 0)
- FWDebugStr("\pdataPbCount < 0, data done");
-
- PBDequeueFirst(pFWXNodeData->pReadDataQHdr, (QElemPtr *) &pb);
- pb->ioMisc = (Ptr) kForkData;
- FWXCommandIsComplete(pb, status);
- }
- else
- FWDebugStr("\pNo receive buffer for data, data done");
- }
-
-
- ////////////////////////////////////////////////////////////////////////////////
- //
- // FWPDriverUnitAdded
- //
- // FireWire protocol driver interface for handling added units.
- //
-
- static OSStatus FWPDriverUnitAdded(
- FWPDriverID fwPDriverID,
- UInt32 fwPDriverSpecificData,
- FWUnitID fwUnitID)
- {
- FWXDriverDataPtr pFWXDriverData;
- OSStatus status = noErr;
-
- // Get our driver data.
- pFWXDriverData = (FWXDriverDataPtr) fwPDriverSpecificData;
-
- status = RegisterFWXNode (pFWXDriverData->fwxDriverID, (UInt32) fwUnitID);
-
- return (status);
- }
-
- ////////////////////////////////////////////////////////////////////////////////
- //
- // FWPDriverUnitRemoved
- //
- // FireWire protocol driver interface for handling removed units.
- //
-
- static OSStatus FWPDriverUnitRemoved(
- FWPDriverID fwPDriverID,
- UInt32 fwPDriverSpecificData,
- FWUnitID fwUnitID)
- {
- FWXDriverDataPtr pFWXDriverData;
- OSStatus status = noErr;
-
- // Get our driver data.
- pFWXDriverData = (FWXDriverDataPtr) fwPDriverSpecificData;
-
- status = UnregisterFWXNode (pFWXDriverData->fwxDriverID, (UInt32) fwUnitID);
-
- return (status);
- }
-
-
- ////////////////////////////////////////////////////////////////////////////////
- //
- // FlowControlCompletion
- //
- // Completion routine for flow control message write
- //
-
- static void FlowControlComplete(
- FWCommandObjectID fwCommandObjectID,
- OSStatus commandStatus,
- UInt32 completionProcData)
- {
- FWXNodeDataPtr pFWXNodeData;
-
- pFWXNodeData = (FWXNodeDataPtr) completionProcData;
- pFWXNodeData->fcSendCommandObjectInUse = false;
- if (commandStatus != noErr)
- {
- if ((commandStatus == timeoutErr) ||
- (commandStatus == retryExceededErr) ||
- (commandStatus == busReconfiguredErr))
- {
- pFWXNodeData->fcSendCommandObjectInUse = true;
- commandStatus = FWWrite(fwCommandObjectID);
- if (commandStatus != noErr)
- pFWXNodeData->fcSendCommandObjectInUse = false;
- }
- else
- {
- sprintf(debugStr,"Error in send flow control: %ld", commandStatus);
- FWDebugStr((ConstStr255Param) c2pstr(debugStr));
- }
- }
- }
-
-
- ////////////////////////////////////////////////////////////////////////////////
- //
- // FlowControlReplyComplete
- //
- // Completion routine for flow control reply write
- //
-
- static void FlowControlReplyComplete(
- FWCommandObjectID fwCommandObjectID,
- OSStatus commandStatus,
- UInt32 completionProcData)
- {
- FWXNodeDataPtr pFWXNodeData;
-
- pFWXNodeData = (FWXNodeDataPtr) completionProcData;
- pFWXNodeData->fcReplyCommandObjectInUse = false;
- if (commandStatus != noErr)
- {
- if ((commandStatus == timeoutErr) ||
- (commandStatus == retryExceededErr) ||
- (commandStatus == busReconfiguredErr))
- {
- commandStatus = FWWrite(fwCommandObjectID);
- if (commandStatus != noErr)
- pFWXNodeData->fcReplyCommandObjectInUse = false;
- }
- else
- {
- sprintf(debugStr,"Error in send flow control: %ld", commandStatus);
- FWDebugStr((ConstStr255Param) c2pstr(debugStr));
- }
- }
- }
-
-
- ////////////////////////////////////////////////////////////////////////////////
- //
- // FWXRead
- //
- // FWiX read routine. This is not a FireWire read routine. This is an
- // interface for the FwiX application to pass read buffers to the
- // driver to handle received data.
- //
- // Queue the application parameter blocks. The FWClientWriteCompleteInterface
- // routine handles the rest. A counter keeps the number of read control parameter
- // blocks which will tell the sender how many control commands it can send.
- // Also keep up with the size of the data buffer to tell the sender how much
- // data can be sent.
- //
-
- static OSStatus FWXRead(
- FWXAsynchParamsPtr pFWXAsynchParams)
- {
- FWXNodeDataPtr pFWXNodeData;
- IOParamPtr pIOParam;
- OSStatus status = noErr;
-
- pFWXNodeData = (FWXNodeDataPtr) pFWXAsynchParams->fwxInterfaceParams.pNodeSpecificData;
- pIOParam = pFWXAsynchParams->pIOPB;
-
- pIOParam->ioActCount = 0;
- if (pIOParam->ioMisc == (Ptr) kForkData)
- {
- status = PBEnqueueLast((QElemPtr) pIOParam, pFWXNodeData->pReadDataQHdr);
- pFWXNodeData->dataPbCount++;
- if (pFWXNodeData->dataPbCount > 6) // value from fwixmain.h
- FWDebugStr("\pdata buffer count too high, FWXRead");
- }
- else
- {
- status = PBEnqueueLast((QElemPtr) pIOParam, pFWXNodeData->pReadControlQHdr);
- pFWXNodeData->controlPbCount++;
- if (pFWXNodeData->dataPbCount > 20) // value from fwixmain.h
- FWDebugStr("\pcontrol buffer count too high, FWXRead");
- }
-
- return status;
- }
-
-
- ////////////////////////////////////////////////////////////////////////////////
- //
- // FWXWrite
- //
- // Queue the write request. If there are no writes in progress, go ahead and
- // issue a write. Otherwise the queued write request will be picked up by
- // the write completion routine.
- //
-
- static OSStatus FWXWrite(
- FWXAsynchParamsPtr pFWXAsynchParams)
- {
- FWXNodeDataPtr pFWXNodeData;
- IOParamPtr pIOParam;
- OSStatus status = noErr;
-
- // recover driver data
- pFWXNodeData = (FWXNodeDataPtr) pFWXAsynchParams->fwxInterfaceParams.pNodeSpecificData;
- pIOParam = pFWXAsynchParams->pIOPB;
-
- // queue the parameter block
- pIOParam->ioActCount = 0;
- PBEnqueueLast((QElemPtr) pIOParam, pFWXNodeData->pWriteQHdr);
-
- if (!pFWXNodeData->writePending)
- {
- pIOParam = (IOParamPtr) pFWXNodeData->pWriteQHdr->qHead;
- if (pIOParam != nil)
- {
- pFWXNodeData->writePending = true;
- pFWXNodeData->pCurIOParam = pIOParam;
- status = SendPacket(pFWXNodeData);
- }
- }
- return status;
- }
-
-
- ////////////////////////////////////////////////////////////////////////////////
- //
- // DataDoneComplete
- //
- // Data done complete routine. Set completion routine back to write complete
- // for asynchCommandObject. Try sending another packet.
- //
-
- static void DataDoneComplete(
- FWCommandObjectID fwCommandObjectID,
- OSStatus commandStatus,
- UInt32 completionProcData)
- {
- FWXNodeDataPtr pFWXNodeData;
- IOParamPtr pb;
-
- // recover node data
- pFWXNodeData = (FWXNodeDataPtr) completionProcData;
-
- // make sure node connection is still open
- if (pFWXNodeData->closed)
- commandStatus = notOpenErr;
-
- if (commandStatus == noErr)
- {
- FWSetFWCommandCompletionProc (fwCommandObjectID, FWXWriteCompletion);
- pFWXNodeData->writeAsynchCommandObjectInUse = false;
-
- // check the queue for more parameter blocks to send
- pb = (IOParamPtr) pFWXNodeData->pWriteQHdr->qHead;
- pFWXNodeData->pCurIOParam = pb;
- if (pb != nil)
- SendPacket(pFWXNodeData);
- else
- pFWXNodeData->writePending = false;
- }
- else if ((commandStatus == timeoutErr) ||
- (commandStatus == retryExceededErr) ||
- (commandStatus == busReconfiguredErr))
- {
- // try sending again
- commandStatus = FWWrite(fwCommandObjectID);
- if (commandStatus != noErr)
- pFWXNodeData->writeAsynchCommandObjectInUse = false;
- }
- else
- {
- pFWXNodeData->writeAsynchCommandObjectInUse = false;
- sprintf(debugStr, "Error in data done complete: %ld", commandStatus);
- FWDebugStr((ConstStr255Param) c2pstr(debugStr));
- }
- }
-
- ////////////////////////////////////////////////////////////////////////////////
- //
- // HandleWriteDataComplete
- //
- // Write data completion routine. If all of the requested data in the
- // current parameter block has been sent, complete the command then
- // dequeue another request and start sending it. If there are no requests
- // waiting, set write complete to true and the next write request will restart
- // the write/write complete loop.
- //
-
- static void HandleWriteDataComplete(
- FWCommandObjectID fwCommandObjectID,
- FWXNodeDataPtr pFWXNodeData,
- IOParamPtr pCompleteIOPb)
- {
- IOParamPtr doneIOParam;
- Ptr dataSent;
- UInt32 dataSum;
- UInt32 actCount;
- UInt32 byteCount;
- OSStatus status;
-
- FWGetAsynchCommandBytesTransferred(fwCommandObjectID, &actCount);
- pCompleteIOPb->ioActCount += actCount;
- pFWXNodeData->dataPbAvail = 0; // turn off flow control to allow for time
- // for receiver to read data out of buffer
-
- pFWXNodeData->writeAsynchCommandObjectInUse = false;
-
- FWGetAsynchCommandBuffer(fwCommandObjectID, &dataSent);
- dataSum = 0;
- for (byteCount = 0; byteCount < actCount; ++byteCount)
- dataSum += dataSent[byteCount];
-
- pFWXNodeData->controlIndex++;
- pFWXNodeData->dataDoneBuffer[0] = pFWXNodeData->controlIndex;
-
- // set packet type, data sent length, checksum
- pFWXNodeData->dataDoneBuffer[1] = kDataDone;
- pFWXNodeData->dataDoneBuffer[2] = actCount;
- pFWXNodeData->dataDoneBuffer[3] = dataSum;
-
- if (!pFWXNodeData->writeAsynchCommandObjectInUse)
- {
- pFWXNodeData->writeAsynchCommandObjectInUse = true;
- FWSetFWCommandCompletionProcData (fwCommandObjectID, (UInt32) pFWXNodeData);
- FWSetCommonAsynchCommandParams (fwCommandObjectID,
- pFWXNodeData->fwxUnitInfo.controlAddress.addressHi,
- pFWXNodeData->fwxUnitInfo.controlAddress.addressLo,
- (Ptr) pFWXNodeData->dataDoneBuffer,
- kDataDoneBufSize);
- FWSetFWCommandCompletionProc (fwCommandObjectID, DataDoneComplete);
-
- // send the data done notification after dequeuing the packet
- status = FWWrite(pFWXNodeData->writeAsynchCommandObjectID);
- if (status != noErr)
- pFWXNodeData->writeAsynchCommandObjectInUse = false;
-
- // if all of the requested data was not sent, send some more
- if (pCompleteIOPb->ioActCount < pCompleteIOPb->ioReqCount)
- {
- FWDebugStr("\pwrite data complete, should not be here");
- SendPacket(pFWXNodeData);
- }
- else
- {
- // completed sending this parameter block, dequeue it and complete
- PBDequeueFirst(pFWXNodeData->pWriteQHdr, (QElemPtr *) &doneIOParam);
- if (doneIOParam->ioCmdAddr != pCompleteIOPb->ioCmdAddr)
- FWDebugStr("\pWrite completion, queued pb not the same as completed pb");
- pFWXNodeData->pCurIOParam = nil;
- FWXCommandIsComplete(doneIOParam, noErr);
- }
-
- }
- else
- FWDebugStr("\pWriteDataComplete, writeAsynchCommandObjectInUse");
- }
-
- ////////////////////////////////////////////////////////////////////////////////
- //
- // HandleWriteControlComplete
- //
- // Write control completion routine. Complete the command then
- // dequeue another request and start sending it. If there are no requests
- // waiting, set write complete to true and the next write request will restart
- // the write/write complete loop.
- //
-
- static void HandleWriteControlComplete(
- FWCommandObjectID fwCommandObjectID,
- FWXNodeDataPtr pFWXNodeData,
- IOParamPtr pCompleteIOPb)
- {
- IOParamPtr doneIOParam;
- UInt32 actCount; // count of bytes transferred
- OSErr err;
-
- FWGetAsynchCommandBytesTransferred(fwCommandObjectID, &actCount);
- pCompleteIOPb->ioActCount += actCount;
-
- // completed sending this parameter block, dequeue it and complete
- err = PBDequeueFirst(pFWXNodeData->pWriteQHdr, (QElemPtr *) &doneIOParam);
- if (doneIOParam->ioCmdAddr != pCompleteIOPb->ioCmdAddr)
- FWDebugStr("\pWriteControlComplete, queued pb not the same as completed pb");
-
- FWXCommandIsComplete(doneIOParam, noErr);
- pFWXNodeData->writeAsynchCommandObjectInUse = false;
-
- // check the queue for more parameter blocks to send
- pCompleteIOPb = (IOParamPtr) pFWXNodeData->pWriteQHdr->qHead;
- pFWXNodeData->pCurIOParam = pCompleteIOPb;
- if (pCompleteIOPb != nil)
- SendPacket(pFWXNodeData);
- else
- pFWXNodeData->writePending = false;
- }
-
- ////////////////////////////////////////////////////////////////////////////////
- //
- // FWXWriteCompletion
- //
- // FWiX write completion routine. If all of the requested data in the
- // current parameter block has been sent, complete the command then
- // dequeue another request and start sending it. If there are no requests
- // waiting, set write complete to true and the next write request will restart
- // the write/write complete loop.
- //
-
- static void FWXWriteCompletion(
- FWCommandObjectID fwCommandObjectID,
- OSStatus commandStatus,
- UInt32 completionProcData)
- {
- FWXNodeDataPtr pFWXNodeData;
- IOParamPtr pIOParam; // param block being processed
- IOParamPtr doneIOParam; // param block being processed
-
- // recover original parameter block
- pFWXNodeData = (FWXNodeDataPtr) completionProcData;
- pIOParam = pFWXNodeData->pCurIOParam;
-
- // make sure node connection is still open
- if (pFWXNodeData->closed)
- commandStatus = notOpenErr;
-
- // check transfer stats and increment actual bytes transferred
- if (commandStatus == noErr)
- {
- if (pIOParam->ioMisc == (Ptr) kForkData)
- HandleWriteDataComplete(fwCommandObjectID, pFWXNodeData, pIOParam);
- else
- HandleWriteControlComplete(fwCommandObjectID, pFWXNodeData, pIOParam);
- }
- else if ((commandStatus == timeoutErr) ||
- (commandStatus == retryExceededErr) ||
- (commandStatus == busReconfiguredErr))
- {
- // got a timeout error, try sending again
- //sprintf(debugStr, "Timeout error in WriteCompletion, pb: %lx", pIOParam);
- //FWDebugStr((ConstStr255Param) c2pstr(debugStr));
- SendPacket(pFWXNodeData);
- }
- else
- {
- // completion routine got an error
- sprintf(debugStr,"Error in write complete: %ld", commandStatus);
- FWDebugStr((ConstStr255Param) c2pstr(debugStr));
-
- pFWXNodeData->writeAsynchCommandObjectInUse = false;
- PBDequeueFirst(pFWXNodeData->pWriteQHdr, (QElemPtr *) &doneIOParam);
- pFWXNodeData->writePending = false;
- FWXCommandIsComplete(doneIOParam, commandStatus);
- }
- }
-
- ////////////////////////////////////////////////////////////////////////////////
- //
- // RetryFlowControl
- //
- // Timer-based routine to request if transmit continue. Check to see if
- // data transmit or control transmit is held and send appropriate request.
- //
- // JKL *** can another flow control write be pending? What if there is no
- // response?
- //
-
- static OSStatus RetryFlowControl(
- void *p1, // node data
- void *p2)
- {
- FWXNodeDataPtr pFWXNodeData;
- IOParamPtr pb;
- OSStatus status = noErr;
-
- pFWXNodeData = (FWXNodeDataPtr) p1;
- pb = pFWXNodeData->pCurIOParam;
-
- // make sure node connection is still open
- if (pFWXNodeData->closed)
- status = notOpenErr;
-
- if ((status == noErr) && (!pFWXNodeData->fcSendCommandObjectInUse))
- {
- if (pb->ioMisc == (Ptr) kForkData)
- pFWXNodeData->fcSendBuffer[0] = kFCDataRequest;
- else
- pFWXNodeData->fcSendBuffer[0] = kFCControlRequest;
-
- pFWXNodeData->fcSendBuffer[2] = pFWXNodeData->fcIndex;
- pFWXNodeData->fcSendCommandObjectInUse = true;
- FWSetFWCommandCompletionProcData (pFWXNodeData->fcSendCommandObjectID, (UInt32) pFWXNodeData);
- FWSetCommonAsynchCommandParams (pFWXNodeData->fcSendCommandObjectID,
- pFWXNodeData->fwxUnitInfo.fcAddress.addressHi,
- pFWXNodeData->fwxUnitInfo.fcAddress.addressLo,
- (Ptr) pFWXNodeData->fcSendBuffer,
- kFlowControlSize);
- status = FWWrite(pFWXNodeData->fcSendCommandObjectID);
- if (status != noErr)
- {
- pFWXNodeData->fcSendCommandObjectInUse = false;
- }
- }
- else
- {
- sprintf(debugStr,"Error in retry flow control: %ld", status);
- FWDebugStr((ConstStr255Param) c2pstr(debugStr));
- }
- return status;
- }
-
- ////////////////////////////////////////////////////////////////////////////////
- //
- // SendDataPacket
- //
- // Send a data packet. If the receive available packet counter is 0
- // then send a flow control request to the receiver to get the number
- // of receive buffers available.
- //
- static OSStatus SendDataPacket(
- FWXNodeDataPtr pFWXNodeData,
- IOParamPtr pb,
- UInt32 length)
- {
- OSStatus status = noErr;
-
- if (pFWXNodeData->dataPbAvail > 0)
- {
- pFWXNodeData->dataPbAvail--;
- pFWXNodeData->writeAsynchCommandObjectInUse = true;
- FWSetFWCommandCompletionProcData (pFWXNodeData->writeAsynchCommandObjectID, (UInt32) pFWXNodeData);
- FWSetCommonAsynchCommandParams (pFWXNodeData->writeAsynchCommandObjectID,
- pFWXNodeData->remoteDataAddress.addressHi,
- pFWXNodeData->remoteDataAddress.addressLo,
- pb->ioBuffer + pb->ioActCount, // increment buffer address
- length);
- status = FWWrite(pFWXNodeData->writeAsynchCommandObjectID);
- if (status != noErr)
- pFWXNodeData->writeAsynchCommandObjectInUse = false;
- }
- else
- {
- pFWXNodeData->fcStopSend = true;
-
- // JKL *** can another flow control write be pending? What if there is no
- // response?
- if (!pFWXNodeData->fcSendCommandObjectInUse)
- {
- pFWXNodeData->fcSendBuffer[0] = kFCDataRequest;
- pFWXNodeData->fcSendBuffer[2] = pFWXNodeData->fcIndex;
- pFWXNodeData->fcSendCommandObjectInUse = true;
- FWSetFWCommandCompletionProcData (pFWXNodeData->fcSendCommandObjectID, (UInt32) pFWXNodeData);
- FWSetCommonAsynchCommandParams (pFWXNodeData->fcSendCommandObjectID,
- pFWXNodeData->fwxUnitInfo.fcAddress.addressHi,
- pFWXNodeData->fwxUnitInfo.fcAddress.addressLo,
- (Ptr) pFWXNodeData->fcSendBuffer,
- kFlowControlSize);
- status = FWWrite(pFWXNodeData->fcSendCommandObjectID);
- if (status != noErr)
- pFWXNodeData->fcSendCommandObjectInUse = false;
- }
- }
- return status;
- }
-
- ////////////////////////////////////////////////////////////////////////////////
- //
- // SendControlPacket
- //
- // Send a control packet. Make sure a control packet is allowed. If none
- // are allowed packet will be sent once allowed notification is received.
- //
-
- static OSStatus SendControlPacket(
- FWXNodeDataPtr pFWXNodeData,
- IOParamPtr pb,
- UInt32 length)
- {
- OSStatus status = noErr;
-
- if (pFWXNodeData->controlPbAvail > 0)
- {
- pFWXNodeData->controlPbAvail--;
- pFWXNodeData->controlIndex++;
- *((UInt32 *) pb->ioBuffer) = pFWXNodeData->controlIndex;
- length += 4;
-
- pFWXNodeData->writeAsynchCommandObjectInUse = true;
- FWSetFWCommandCompletionProcData (pFWXNodeData->writeAsynchCommandObjectID, (UInt32) pFWXNodeData);
- FWSetCommonAsynchCommandParams (pFWXNodeData->writeAsynchCommandObjectID,
- pFWXNodeData->fwxUnitInfo.controlAddress.addressHi,
- pFWXNodeData->fwxUnitInfo.controlAddress.addressLo,
- pb->ioBuffer,
- length);
- status = FWWrite(pFWXNodeData->writeAsynchCommandObjectID);
- if (status != noErr)
- pFWXNodeData->writeAsynchCommandObjectInUse = false;
- }
- else
- {
- pFWXNodeData->fcStopSend = true;
-
- // JKL *** can another flow control write be pending? What if there is no
- // response?
- if (!pFWXNodeData->fcSendCommandObjectInUse)
- {
- pFWXNodeData->fcSendBuffer[0] = kFCControlRequest;
- pFWXNodeData->fcSendBuffer[2] = pFWXNodeData->fcIndex;
- pFWXNodeData->fcSendCommandObjectInUse = true;
- FWSetFWCommandCompletionProcData (pFWXNodeData->fcSendCommandObjectID, (UInt32) pFWXNodeData);
- FWSetCommonAsynchCommandParams (pFWXNodeData->fcSendCommandObjectID,
- pFWXNodeData->fwxUnitInfo.fcAddress.addressHi,
- pFWXNodeData->fwxUnitInfo.fcAddress.addressLo,
- (Ptr) pFWXNodeData->fcSendBuffer,
- kFlowControlSize);
- status = FWWrite(pFWXNodeData->fcSendCommandObjectID);
- if (status != noErr)
- pFWXNodeData->fcSendCommandObjectInUse = false;
- }
- }
- return status;
- }
-
- ////////////////////////////////////////////////////////////////////////////////
- //
- // SendPacket
- //
- // Check for the packet needs data to be sent. Pass it off to the senddata
- // or sendcontrol routine. If no data, complete the command.
- //
-
- static OSStatus SendPacket(
- FWXNodeDataPtr pFWXNodeData)
- {
- IOParamPtr pb;
- OSStatus status = noErr;
-
- if (pFWXNodeData->fcStopSend)
- FWDebugStr("\pIn SendPacket with stop flow control");
-
- pb = pFWXNodeData->pCurIOParam;
- if (pb != nil)
- {
- if (pb->ioMisc == (Ptr) kForkData)
- status = SendDataPacket(pFWXNodeData, pb, pb->ioReqCount);
- else
- status = SendControlPacket(pFWXNodeData, pb, pb->ioReqCount);
- }
-
- return status;
- }
-
- ////////////////////////////////////////////////////////////////////////////////
- //
- // FWXDriverInterface
- //
- // Main FireWire File Exchange driver interface.
- //
-
- OSStatus FWXDriverInterface (
- FWXInterfaceParamsPtr pFWXInterfaceParams)
- {
- FWXNodeDataPtr pFWXNodeData;
- IOParamPtr pIOPB;
- UInt32 interfaceSelector;
- OSStatus err = noErr;
-
- // Get our driver and node info
- pFWXNodeData =
- (FWXNodeDataPtr) pFWXInterfaceParams->pNodeSpecificData;
- interfaceSelector = pFWXInterfaceParams->interfaceSelector;
-
- // Main dispatch.
- switch (interfaceSelector) {
-
- case kFWXInitialize :
- err = FWXInitialize((FWXInitializeParamsPtr) pFWXInterfaceParams);
- break;
-
- case kFWXTerminate :
- err = FWXTerminate((FWXTerminateParamsPtr) pFWXInterfaceParams);
- break;
-
- case kFWXWrite :
- err = FWXWrite((FWXAsynchParamsPtr) pFWXInterfaceParams);
- break;
-
- case kFWXRead :
- err = FWXRead((FWXAsynchParamsPtr) pFWXInterfaceParams);
- break;
-
- case kFWXKillIO :
- pFWXNodeData->writePending = false;
-
- // clean up any pending reads
- err = PBDequeueFirst(pFWXNodeData->pReadControlQHdr, (QElemPtr *) &pIOPB);
- while ((pIOPB != nil) && (err == noErr)) {
- pIOPB->ioActCount = 0;
- FWXCommandIsComplete(pIOPB, noErr);
- err = PBDequeueFirst(pFWXNodeData->pReadControlQHdr, (QElemPtr *) &pIOPB);
- }
-
- err = PBDequeueFirst(pFWXNodeData->pReadDataQHdr, (QElemPtr *) &pIOPB);
- while ((pIOPB != nil) && (err == noErr)) {
- pIOPB->ioActCount = 0;
- FWXCommandIsComplete(pIOPB, noErr);
- err = PBDequeueFirst(pFWXNodeData->pReadDataQHdr, (QElemPtr *) &pIOPB);
- }
- pFWXNodeData->dataPbCount = 0;
- pFWXNodeData->controlPbCount = 0;
- pFWXNodeData->dataPbAvail = 0;
- pFWXNodeData->controlPbAvail = 0;
- break;
-
- case kFWXOpenNode:
- err = FWXOpenNode((FWXOpenNodeParamsPtr) pFWXInterfaceParams);
- break;
-
- case kFWXCloseNode:
- err = FWXCloseNode((FWXNodeDataPtr) (pFWXInterfaceParams->pNodeSpecificData));
- break;
-
- default :
- err = paramErr;
- break;
- }
-
- return err;
- }
-
- ////////////////////////////////////////////////////////////////////////////////
- //
- // FWXInitialize
- //
- // This routine initializes the FireWire File Exchange driver. It
- // allocates a private data record and registers with the FireWire family.
- //
-
- static OSStatus FWXInitialize(
- FWXInitializeParamsPtr pFWXInitializeParams)
- {
- FWPDriverProtocol fwPDriverProtocolTable[1];
- Ptr pBuffer = nil;
- FWXDriverDataPtr pFWXDriverData;
- OSStatus status = noErr;
-
- // FWDebugStr("\pfwix driver init");
- // Allocate driver data.
- pFWXDriverData = (FWXDriverDataPtr) PoolAllocateResident(sizeof(FWXDriverData), true);
- if (pFWXDriverData != nil)
- pFWXDriverData->fwxDriverID = pFWXInitializeParams->fwxDriverID;
- else
- status = memFullErr;
-
- // Allocate a control buffer
- if (status == noErr)
- {
- pBuffer = PoolAllocateResident(kFWControlBufferSize, false);
- if (pBuffer == nil)
- {
- PoolDeallocate((Ptr) pFWXDriverData);
- pFWXDriverData = nil;
- status = memFullErr;
- }
- else
- pFWXDriverData->controlBuffer = pBuffer;
- }
-
- // Allocate a flow control receive buffer
- if (status == noErr)
- {
- pBuffer = PoolAllocateResident(kFlowControlSize, true);
- if (pBuffer == nil)
- {
- PoolDeallocate(pFWXDriverData->controlBuffer);
- PoolDeallocate((Ptr) pFWXDriverData);
- pFWXDriverData = nil;
- status = memFullErr;
- }
- else
- pFWXDriverData->fcBuffer = pBuffer;
- }
-
- // Register with the FireWire family.
- if (status == noErr)
- {
- status = FWRegisterProtocolDriver (pFWXInitializeParams->pDriverRegEntry,
- &(pFWXDriverData->fwPDriverID),
- (UInt32) pFWXDriverData);
- }
-
- // Set protocol table.
- if (status == noErr)
- {
- fwPDriverProtocolTable[0].specID = 'app';
- fwPDriverProtocolTable[0].swVersion = 'fwx';
- status = FWSetPDriverProtocolTable (pFWXDriverData->fwPDriverID,
- &fwPDriverProtocolTable[0],
- 1);
- }
-
- // Set unit notification procs.
- if (status == noErr)
- {
- status = FWSetFWPDriverUnitAddedProc (pFWXDriverData->fwPDriverID,
- FWPDriverUnitAdded);
- }
- if (status == noErr)
- {
- status = FWSetFWPDriverUnitRemovedProc (pFWXDriverData->fwPDriverID,
- FWPDriverUnitRemoved);
- }
-
- // Scan for units.
- if (status == noErr)
- status = FWScanUnitsForFWPDriver (pFWXDriverData->fwPDriverID);
-
- // set driver write notify routine
- if (status == noErr)
- {
- status = FWSetFWClientWriteCompleteProc((FWReferenceID) pFWXDriverData->fwPDriverID,
- FWClientWriteCompleteInterface);
- }
-
- // Get address space for control buffer: allow write and notify on write
- if (status == noErr)
- {
- status = FWAllocateAddressSpace
- (&pFWXDriverData->controlAddressSpaceID,
- (FWReferenceID) pFWXDriverData->fwPDriverID,
- &(pFWXDriverData->controlAddress),
- kFWControlBufferSize,
- pFWXDriverData->controlBuffer,
- kFWAddressWriteEnable | kFWAddressWriteCompleteNotify,
- (Ptr) pFWXDriverData);
- }
-
- // Get address space for flow control buffer: allow write, notify on write
- if (status == noErr)
- {
- status = FWAllocateAddressSpace
- (&pFWXDriverData->fcAddressSpaceID,
- (FWReferenceID) pFWXDriverData->fwPDriverID,
- &(pFWXDriverData->fcAddress),
- kFlowControlSize,
- (Ptr) pFWXDriverData->fcBuffer,
- kFWAddressWriteEnable | kFWAddressWriteCompleteNotify,
- (Ptr) pFWXDriverData);
- }
-
- // Create a unit directory.
- if (status == noErr)
- {
- status = FWXCreatePDriverUnitDirectory (pFWXDriverData,
- &(pFWXDriverData->unitCSRROMEntryID));
- }
-
-
- // Save our driver data or clean up on error.
- if (status == noErr)
- {
- pFWXInitializeParams->fwxInterfaceParams.pDriverSpecificData =
- (Ptr) pFWXDriverData;
- }
- else
- {
- //zzz should use terminate
- // deallocate more stuff, asynch object?
- if (pFWXDriverData->fcBuffer != nil)
- PoolDeallocate((Ptr) pFWXDriverData->fcBuffer);
- if (pFWXDriverData->controlBuffer != nil)
- PoolDeallocate(pFWXDriverData->controlBuffer);
- if (pFWXDriverData != nil)
- PoolDeallocate((Ptr) pFWXDriverData);
-
- pFWXInitializeParams->fwxInterfaceParams.pDriverSpecificData = nil;
- }
- return status;
- }
-
-
- ////////////////////////////////////////////////////////////////////////////////
- //
- // FWXCreatePDriverUnitDirectory
- //
- // This routine adds a Configuration ROM unit directory for the protocol driver.
- //zzz must do cleanup on error.
- //
-
- static OSStatus FWXCreatePDriverUnitDirectory(
- FWXDriverDataPtr pFWXDriverData,
- CSRROMEntryID *pFWPDriverCSRROMUnitDirID)
- {
- CSRROMEntryID csrROMRootEntryID = kInvalidCSRROMEntryID,
- csrROMUnitDirEntryID = kInvalidCSRROMEntryID,
- csrROMEntryID = kInvalidCSRROMEntryID;
- FWXUnitInfo fwxUnitInfo;
- UInt32 immediateEntry;
- OSStatus status = noErr;
-
- // Get configuration ROM root directory.
- status = FWCSRROMGetRootDirectory (pFWXDriverData->fwPDriverID, &csrROMRootEntryID);
-
- // Create a new unit directory.
- if (status == noErr)
- {
- status = FWCSRROMCreateEntry (csrROMRootEntryID,
- &csrROMUnitDirEntryID,
- kDirectoryCSRROMEntryType,
- kCSRUnitDirectoryKey,
- nil,
- 0);
- if (status == noErr)
- pFWXDriverData->unitCSRROMEntryID = csrROMUnitDirEntryID;
- }
-
- // Set unit's spec ID.
- if (status == noErr)
- {
- immediateEntry = 'app ';
- status = FWCSRROMCreateEntry (csrROMUnitDirEntryID,
- &csrROMEntryID,
- kImmediateCSRROMEntryType,
- kCSRUnitSpecIdKey,
- (Ptr) &immediateEntry,
- 3);
- }
-
- // Set unit's SW Version.
- if (status == noErr)
- {
- immediateEntry = 'fwx ';
- status = FWCSRROMCreateEntry (csrROMUnitDirEntryID,
- &csrROMEntryID,
- kImmediateCSRROMEntryType,
- kCSRUnitSwVersionKey,
- (Ptr) &immediateEntry,
- 3);
- }
-
- // Create unit dependent leaf.
- if (status == noErr)
- {
- // Fill in data for FWiX unit info leaf.
- fwxUnitInfo.controlAddress.addressHi = pFWXDriverData->controlAddress.addressHi;
- fwxUnitInfo.controlAddress.addressLo = pFWXDriverData->controlAddress.addressLo;
- fwxUnitInfo.fcAddress.addressHi = pFWXDriverData->fcAddress.addressHi;
- fwxUnitInfo.fcAddress.addressLo = pFWXDriverData->fcAddress.addressLo;
-
- // Create the leaf.
- status = FWCSRROMCreateEntry (csrROMUnitDirEntryID,
- &csrROMEntryID,
- kLeafCSRROMEntryType,
- kCSRUnitDependentInfoKey,
- (Ptr) &fwxUnitInfo,
- sizeof (FWXUnitInfo));
- }
-
- // Instantiate CSR ROM.
- if (status == noErr)
- status = FWCSRROMInstantiate (pFWXDriverData->fwPDriverID);
-
- // Clean up.
- if (csrROMRootEntryID != (CSRROMEntryID) kInvalidCSRROMEntryID)
- FWCSRROMDisposeEntryID (csrROMRootEntryID);
-
- if (csrROMEntryID != (CSRROMEntryID) kInvalidCSRROMEntryID)
- FWCSRROMDisposeEntryID (csrROMEntryID);
-
- // Return unit directory ID.
- if (status == noErr)
- *pFWPDriverCSRROMUnitDirID = csrROMUnitDirEntryID;
- else
- *pFWPDriverCSRROMUnitDirID = kInvalidCSRROMEntryID;
-
- return (status);
- }
-
-
- ////////////////////////////////////////////////////////////////////////////////
- //
- // FWXTerminate
- //
- // This routine terminates the FireWire File Exchange driver. It
- // deallocates a private data record and unregisters with the FireWire family.
- //zzz need to do more deallocation:
- // xmit and receive buffers
- // CSR ROM unit dir entry
- //
- //
-
- static OSStatus FWXTerminate(
- FWXTerminateParamsPtr pFWXTerminateParams)
- {
- FWXDriverDataPtr pFWXDriverData;
- OSStatus status = noErr;
-
- // FWDebugStr("\pfwix driver terminate");
- // Get driver data from params.
- pFWXDriverData = (FWXDriverDataPtr)
- pFWXTerminateParams->fwxInterfaceParams.pDriverSpecificData;
-
- // Deallocate our driver data.
- if (pFWXDriverData != nil) {
-
- if (pFWXDriverData->unitCSRROMEntryID != (CSRROMEntryID) kInvalidCSRROMEntryID)
- FWCSRROMDisposeEntryID (pFWXDriverData->unitCSRROMEntryID);
-
- if (pFWXDriverData->controlBuffer != nil)
- PoolDeallocate((Ptr) pFWXDriverData->controlBuffer);
-
- if (pFWXDriverData->fcBuffer != nil)
- PoolDeallocate((Ptr) pFWXDriverData->fcBuffer);
-
- // Unregister with FireWire family.
- FWUnregisterProtocolDriver(pFWXDriverData->fwPDriverID);
-
- // Deallocate our driver data.
- PoolDeallocate((Ptr) pFWXDriverData);
- }
-
- return status;
- }
-
- ////////////////////////////////////////////////////////////////////////////////
- //
- // FWXOpenNode
- //
- // This routine opens a connections to a remote FWiX node. Allocate a bunch
- // of buffers and get the remote node's info. Have to send the node our data
- // address space for him. Use the flow control asynch object and buffers to
- // handle this. Why? Its there and the right size.
- //
-
- static OSStatus FWXOpenNode(
- FWXOpenNodeParamsPtr pFWXInitializeParams)
- {
- FWXDriverDataPtr pFWXDriverData;
- FWXNodeDataPtr pFWXNodeData = nil;
- CSRROMEntryIterator csrROMIterator = kInvalidCSRROMIterator;
- CSRROMSearchCriteria searchCriteria;
- CSRROMEntryID unitCSRROMEntryID,
- unitInfoCSRROMEntryID = kInvalidCSRROMEntryID;
- UInt32 unitInfoSize;
- FWCommandObjectID asynchCommandObjectID;
- Boolean done;
- OSStatus status = noErr;
-
- // FWDebugStr("\pFWXOpenNode");
- // Get our driver data.
- pFWXDriverData = (FWXDriverDataPtr) pFWXInitializeParams->fwxInterfaceParams.pDriverSpecificData;
-
- // Allocate a node data record
- pFWXNodeData = (FWXNodeDataPtr) PoolAllocateResident (sizeof (FWXNodeData), true);
- if (pFWXNodeData != nil)
- {
- pFWXNodeData->fwUnitID =
- (FWUnitID) pFWXInitializeParams->fwxNodeRegistrationReference;
- pFWXNodeData->pFWXDriverData = pFWXDriverData;
- }
- else
- status = memFullErr;
-
- // Allocate a flow control send buffer
- if (status == noErr)
- {
- pFWXNodeData->fcSendBuffer = (SInt32 *) PoolAllocateResident(kFlowControlSize, false);
- if (pFWXNodeData->fcSendBuffer == nil)
- status = memFullErr;
- }
-
- // Allocate a flow control reply buffer
- if (status == noErr)
- {
- pFWXNodeData->fcReplyBuffer = (SInt32 *) PoolAllocateResident(kFlowControlSize, false);
- if (pFWXNodeData->fcReplyBuffer == nil)
- status = memFullErr;
- }
-
- // Allocate a data done buffer
- if (status == noErr)
- {
- pFWXNodeData->dataDoneBuffer = (SInt32 *) PoolAllocateResident(kDataDoneBufSize, false);
- if (pFWXNodeData->dataDoneBuffer == nil)
- status = memFullErr;
- }
-
- // Allocate a data buffer and get address space, have to send this to the
- // node after the rest of the allocations
- if (status == noErr)
- {
- pFWXNodeData->dataBuffer = PoolAllocateResident(kFWDataBufferSize, false);
- if (pFWXNodeData->dataBuffer != nil)
- {
- // Get address space for data buffer: allow write, notify is handled with data done message
- status = FWAllocateAddressSpace (&pFWXNodeData->localDataAddressSpaceID,
- (FWReferenceID) pFWXDriverData->fwPDriverID,
- &pFWXNodeData->localDataAddress,
- kFWDataBufferSize,
- pFWXNodeData->dataBuffer,
- kFWAddressWriteEnable,
- (Ptr) pFWXDriverData);
- }
- else
- status = memFullErr;
- }
-
- // Add node data record to driver's list.
- if (status == noErr)
- {
- if (pFWXDriverData->fwxNodeDataList != nil)
- pFWXDriverData->fwxNodeDataList->pPrevFWXNodeData = pFWXNodeData;
-
- pFWXNodeData->pPrevFWXNodeData = nil;
- pFWXNodeData->pNextFWXNodeData = pFWXDriverData->fwxNodeDataList;
-
- pFWXDriverData->fwxNodeDataList = pFWXNodeData;
- }
-
- // Get node's device ID.
- if (status == noErr)
- {
- status = FWGetFWDeviceIDFromFWReferenceID ((FWReferenceID) pFWXNodeData->fwUnitID,
- &(pFWXNodeData->fwDeviceID));
- }
-
- // Get node's unit dependent information.
- if (status == noErr)
- {
- // Get unit CSR ROM entry ID.
- status = FWGetUnitCSRROMEntryID ((FWReferenceID) pFWXNodeData->fwUnitID,
- &unitCSRROMEntryID);
-
- // Create a CSR ROM search iterator.
- if (status == noErr) {
- status = FWCSRROMCreateIterator (&csrROMIterator,
- (FWReferenceID) pFWXNodeData->fwUnitID);
- }
-
- // Set iterator to start searching at our unit directory.
- if (status == noErr) {
- status = FWCSRROMSetIterator (csrROMIterator,
- unitCSRROMEntryID,
- kIterateDescendants);
- }
-
- // Search for unit dependent info leaf.
- if (status == noErr) {
- searchCriteria.csrROMSearchType = kCSRROMSearchForKey;
- searchCriteria.keyType = kCSRLeafKeyTypeBit;
- searchCriteria.keyHi = kCSRUnitDependentInfoKeyHiBit;
- searchCriteria.keyLo = kCSRUnitDependentInfoKeyLoBit;
- unitInfoSize = sizeof (FWXUnitInfo);
- status = FWCSRROMEntrySearch (csrROMIterator,
- kIterateContinue,
- &unitInfoCSRROMEntryID,
- &done,
- &searchCriteria,
- (Ptr) &(pFWXNodeData->fwxUnitInfo),
- &unitInfoSize);
- }
-
- // Clean up.
- if (csrROMIterator != (CSRROMEntryIterator) kInvalidCSRROMIterator)
- FWCSRROMDisposeIterator (csrROMIterator);
- if (unitInfoCSRROMEntryID != (CSRROMEntryIterator) kInvalidCSRROMEntryID)
- FWCSRROMDisposeEntryID (unitInfoCSRROMEntryID);
- }
-
- // Allocate FireWire command object for sending asynchronous write packets.
- if (status == noErr)
- {
- status = FWAllocateAsynchCommandObject(&asynchCommandObjectID);
- if (status == noErr)
- {
- pFWXNodeData->writeAsynchCommandObjectID = asynchCommandObjectID;
- FWSetFWCommandParams(asynchCommandObjectID,
- (FWReferenceID) pFWXNodeData->fwUnitID,
- 0,
- FWXWriteCompletion,
- (UInt32) pFWXInitializeParams->fwxInterfaceParams.pDriverSpecificData);
- FWSetAsynchCommandMaxRetries(asynchCommandObjectID, 8);
- }
- }
-
- #ifdef FireBug
- FireBugPrep ((FWReferenceID) pFWXNodeData->fwUnitID);
- sprintf (fireBug, "FWiX FireBug service ready on %s", "(unknown)"); // could add some kind of ID
- FireBugMsg (fireBug);
- #endif
-
- // Allocate FireWire command object for sending flow control packets.
- if (status == noErr)
- {
- status = FWAllocateAsynchCommandObject(&asynchCommandObjectID);
- if (status == noErr)
- {
- pFWXNodeData->fcSendCommandObjectID = asynchCommandObjectID;
- FWSetFWCommandParams (asynchCommandObjectID,
- (FWReferenceID) pFWXNodeData->fwUnitID,
- 0,
- FlowControlComplete,
- (UInt32) pFWXInitializeParams->fwxInterfaceParams.pDriverSpecificData);
- FWSetAsynchCommandMaxRetries(asynchCommandObjectID, 8);
- }
- }
-
- // Allocate FireWire command object for replying with flow control packets.
- if (status == noErr)
- {
- status = FWAllocateAsynchCommandObject(&asynchCommandObjectID);
- if (status == noErr)
- {
- pFWXNodeData->fcReplyCommandObjectID = asynchCommandObjectID;
- FWSetFWCommandParams(asynchCommandObjectID,
- (FWReferenceID) pFWXNodeData->fwUnitID,
- 0,
- FlowControlReplyComplete,
- (UInt32) pFWXInitializeParams->fwxInterfaceParams.pDriverSpecificData);
- FWSetAsynchCommandMaxRetries(asynchCommandObjectID, 8);
- }
- }
-
- // setup IO queues
- if (status == noErr)
- status = SetupIOQueues(pFWXNodeData);
-
- if (status == noErr)
- FWSetMaxPayloadSize((FWReferenceID) pFWXNodeData->fwUnitID, kFWPacketSize);
-
- // Open a connection to the unit.
- if (status == noErr) {
- status = FWAddUnitConnection
- (pFWXNodeData->fwUnitID, (FWReferenceID) pFWXDriverData->fwPDriverID);
- if (status == noErr)
- pFWXNodeData->unitConnectionAdded = true;
- }
-
- // Init control packets to some safe value, this will enable flow control to start
- if (status == noErr)
- {
- pFWXNodeData->controlPbAvail = 5;
- }
-
- // Send the data address space to the remote node using the flow control request packet
- // JKL *** can this fail, retry?
- if (status == noErr)
- {
- pFWXNodeData->fcSendCommandObjectInUse = true;
- pFWXNodeData->fcSendBuffer[0] = kAddressInfoRequest;
- pFWXNodeData->fcSendBuffer[1] = pFWXNodeData->localDataAddress.addressHi;
- pFWXNodeData->fcSendBuffer[2] = pFWXNodeData->localDataAddress.addressLo;
- FWSetFWCommandCompletionProcData (pFWXNodeData->fcSendCommandObjectID, (UInt32) pFWXNodeData);
- FWSetCommonAsynchCommandParams (pFWXNodeData->fcSendCommandObjectID,
- pFWXNodeData->fwxUnitInfo.fcAddress.addressHi,
- pFWXNodeData->fwxUnitInfo.fcAddress.addressLo,
- (Ptr) pFWXNodeData->fcSendBuffer,
- kFlowControlSize);
- status = FWWrite(pFWXNodeData->fcSendCommandObjectID);
- if (status != noErr)
- pFWXNodeData->fcSendCommandObjectInUse = false;
- }
-
- // Clean up on error.
- if (status != noErr) {
- if (pFWXNodeData != nil)
- {
- sprintf(debugStr,"Closing node from OpenNode, error: %ld", status);
- FWDebugStr((ConstStr255Param) c2pstr(debugStr));
- FWXCloseNode (pFWXNodeData);
- }
- }
-
- // Return results.
- if (status == noErr)
- pFWXInitializeParams->fwxInterfaceParams.pNodeSpecificData = (Ptr) pFWXNodeData;
- else
- pFWXInitializeParams->fwxInterfaceParams.pNodeSpecificData = nil;
-
- return status;
- }
-
- ////////////////////////////////////////////////////////////////////////////////
- //
- // FWXCloseNode
- //
- // This routine closes a connections to a remote FWiX node.
- //
- static OSStatus FWXCloseNode(
- FWXNodeDataPtr pFWXNodeData)
- {
- FWXDriverDataPtr pFWXDriverData;
- FWXNodeDataPtr pPrevFWXNodeData,
- pNextFWXNodeData;
- volatile Boolean *pFWCommandObjectInUse;
- IOParamPtr pIOPB;
- AbsoluteTime timeRemaining;
- OSStatus status = noErr;
-
- // FWDebugStr("\pFWXCloseNode");
- if (pFWXNodeData != nil) {
- // Get our driver data.
- pFWXDriverData = (FWXDriverDataPtr) pFWXNodeData->pFWXDriverData;
-
- // Set node closed.
- pFWXNodeData->closed = true;
- CancelTimer(pFWXNodeData->fcTimerID, &timeRemaining);
-
- // Wait for all command objects to be no longer in use.
- pFWCommandObjectInUse = &(pFWXNodeData->writeAsynchCommandObjectInUse);
- while (*pFWCommandObjectInUse);
- pFWCommandObjectInUse = &(pFWXNodeData->fcSendCommandObjectInUse);
- while (*pFWCommandObjectInUse);
- pFWCommandObjectInUse = &(pFWXNodeData->fcReplyCommandObjectInUse);
- while (*pFWCommandObjectInUse);
-
- // Deallocate queues, write queue
- if (pFWXNodeData->pWriteQHdr != nil) {
- pIOPB = (IOParamPtr) pFWXNodeData->pWriteQHdr->qHead;
- while (pIOPB != nil) {
- PBDequeueFirst(pFWXNodeData->pWriteQHdr, (QElemPtr *) &pIOPB);
- pIOPB->ioActCount = 0;
- FWXCommandIsComplete(pIOPB, noErr);
- pIOPB = (IOParamPtr) pFWXNodeData->pWriteQHdr->qHead;
- }
- PBQueueDelete(pFWXNodeData->pWriteQHdr);
- }
-
- if (pFWXNodeData->pReadControlQHdr != nil) {
- pIOPB = (IOParamPtr) pFWXNodeData->pReadControlQHdr->qHead;
- while (pIOPB != nil) {
- PBDequeueFirst(pFWXNodeData->pReadControlQHdr, (QElemPtr *) &pIOPB);
- pIOPB->ioActCount = 0;
- FWXCommandIsComplete(pIOPB, noErr);
- pIOPB = (IOParamPtr) pFWXNodeData->pReadControlQHdr->qHead;
- }
- PBQueueDelete(pFWXNodeData->pReadControlQHdr);
- }
-
- if (pFWXNodeData->pReadDataQHdr != nil) {
- pIOPB = (IOParamPtr) pFWXNodeData->pReadDataQHdr->qHead;
- while (pIOPB != nil) {
- PBDequeueFirst(pFWXNodeData->pReadDataQHdr, (QElemPtr *) &pIOPB);
- pIOPB->ioActCount = 0;
- FWXCommandIsComplete(pIOPB, noErr);
- pIOPB = (IOParamPtr) pFWXNodeData->pReadDataQHdr->qHead;
- }
- PBQueueDelete(pFWXNodeData->pReadDataQHdr);
- pFWXNodeData->dataPbCount = 0;
- pFWXNodeData->controlPbCount = 0;
- pFWXNodeData->dataPbAvail = 0;
- pFWXNodeData->controlPbAvail = 0;
- }
-
- // Deallocate command object for sending asynchronous write packets.
- if (pFWXNodeData->writeAsynchCommandObjectID != (FWCommandObjectID) kInvalidFWCommandObjectID)
- FWDeallocateFWCommandObject (pFWXNodeData->writeAsynchCommandObjectID);
-
- // Deallocate command objects for flow control packets.
- if (pFWXNodeData->fcSendCommandObjectID != (FWCommandObjectID) kInvalidFWCommandObjectID)
- FWDeallocateFWCommandObject (pFWXNodeData->fcSendCommandObjectID);
- if (pFWXNodeData->fcReplyCommandObjectID != (FWCommandObjectID) kInvalidFWCommandObjectID)
- FWDeallocateFWCommandObject (pFWXNodeData->fcReplyCommandObjectID);
-
- // Remove node data record from driver's list.
- pPrevFWXNodeData = pFWXNodeData->pPrevFWXNodeData;
- pNextFWXNodeData = pFWXNodeData->pNextFWXNodeData;
-
- // Remove our connection to unit.
- if (pFWXNodeData->unitConnectionAdded) {
- FWRemoveUnitConnection (pFWXNodeData->fwUnitID,
- (FWReferenceID) pFWXDriverData->fwPDriverID);
- }
-
- if (pPrevFWXNodeData != nil) {
- pPrevFWXNodeData->pNextFWXNodeData = pNextFWXNodeData;
- } else {
- if (pFWXDriverData->fwxNodeDataList == pFWXNodeData)
- pFWXDriverData->fwxNodeDataList = pNextFWXNodeData;
- }
-
- if (pNextFWXNodeData != nil)
- pNextFWXNodeData->pPrevFWXNodeData = pPrevFWXNodeData;
-
- // Deallocate buffers
- if (pFWXNodeData->fcSendBuffer != nil)
- PoolDeallocate ((Ptr) pFWXNodeData->fcSendBuffer);
- if (pFWXNodeData->fcReplyBuffer != nil)
- PoolDeallocate ((Ptr) pFWXNodeData->fcReplyBuffer);
- if (pFWXNodeData->dataDoneBuffer != nil)
- PoolDeallocate ((Ptr) pFWXNodeData->dataDoneBuffer);
- if (pFWXNodeData->dataBuffer != nil)
- PoolDeallocate((Ptr) pFWXNodeData->dataBuffer);
-
- // Deallocate address space
- FWDeallocateAddressSpace(pFWXNodeData->localDataAddressSpaceID);
-
- // Deallocate node data record.
- PoolDeallocate ((Ptr) pFWXNodeData);
- }
-
- return status;
- }
-
- //////////////////////////////////////////////////////////////////////////////
- //
- // SetupIOQueues
- //
- // Setup the queueus. Create and initialize.
- //
- static OSStatus SetupIOQueues(
- FWXNodeDataPtr pFWXNodeData)
- {
- OSStatus status = noErr;
-
- status = PBQueueCreate(& pFWXNodeData->pReadDataQHdr);
- if (status == noErr)
- PBQueueInit(pFWXNodeData->pReadDataQHdr);
- else
- return status;
-
- status = PBQueueCreate(& pFWXNodeData->pReadControlQHdr);
- if (status == noErr)
- PBQueueInit(pFWXNodeData->pReadControlQHdr);
- else
- return status;
-
- status = PBQueueCreate(& pFWXNodeData->pWriteQHdr);
- if (status == noErr)
- PBQueueInit(pFWXNodeData->pWriteQHdr);
-
- return status;
- }
-
- //////////////////////////////////////////////////////////////////////////////
- //
- // FWXGetNodeDataFromNodeID
- //
- // Return the FWX node data record that matches the given node ID.
- //
- static OSStatus FWXGetNodeDataFromNodeID (
- FWXDriverDataPtr pFWXDriverData,
- UInt32 generation,
- UInt32 nodeID,
- FWXNodeDataPtr *ppFWXNodeData)
- {
- FWXNodeDataPtr pFWXNodeData;
- FWDeviceID fwDeviceID;
- Boolean found;
- OSStatus status = noErr;
-
- // Get FireWire device ID for nodeID.
- status = FWFindFWDeviceFromNodeID (pFWXDriverData->fwPDriverID,
- generation,
- nodeID,
- &fwDeviceID);
-
- // Search node data list for node with matching deviceID.
- if (status == noErr) {
- pFWXNodeData = pFWXDriverData->fwxNodeDataList;
- found = false;
- while ((pFWXNodeData != nil) && (!found))
- {
- if ((pFWXNodeData->fwDeviceID == fwDeviceID) && (!(pFWXNodeData->closed)))
- found = true;
- else
- pFWXNodeData = pFWXNodeData->pNextFWXNodeData;
- }
- }
-
- // Return results.
- if (status == noErr) {
- if (found) {
- *ppFWXNodeData = pFWXNodeData;
- } else {
- *ppFWXNodeData = nil;
- status = notFoundErr;
- }
- } else {
- *ppFWXNodeData = nil;
- }
-
- return (status);
- }
-